//
// Ishtar C++ Utility Library
//
// Value Amenity - Ordinal Integer Header
//

#ifndef __ISHTAR_VALUE_ORDINAL_INTEGER_H
#define __ISHTAR_VALUE_ORDINAL_INTEGER_H

#include <Ishtar/Ishtar.h>

#if defined( ISHTAR_COMPILER_HAS_PRAGMA_ONCE )
#pragma once
#endif

#include <boost/static_assert.hpp>
#include <boost/operators.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <Ishtar/IntegerConvertible.h>
#include <Ishtar/Io/IoData.h>


namespace Ishtar
{

///////////////////////////////////////////////////////////////////////////////
//
// Ordinal Integer
// - A convenient integer wrapper class to behave an identifier types.
//

template< typename Derived, typename ValueType >
class OrdinalInteger : public IoData< Derived, ValueType >
                     , public boost::totally_ordered< OrdinalInteger< Derived, ValueType > >
{
    BOOST_STATIC_ASSERT( boost::is_integral< ValueType >::value );

public:

    /// Constructors ///

    OrdinalInteger() : m_value( 0 ) {}
    explicit OrdinalInteger( ValueType value ) : m_value( value ) {}


    /// Predicates ///

    Bool operator==( const OrdinalInteger& rhs ) const { return m_value == rhs.m_value; }
    Bool operator< ( const OrdinalInteger& rhs ) const { return m_value <  rhs.m_value; }


    /// Accessors ///

    ValueType Value() const { return m_value; }


private:
    ValueType m_value;
};


///////////////////////////////////////////////////////////////////////////////
//
// Macro Defines
//

#define ISHTAR_ORDINAL_INTEGER_DEFINE( derived, valueType, defaultValue ) \
    derived() : OrdinalInteger< derived, valueType >( defaultValue ) {} \
    explicit derived( valueType value ) : OrdinalInteger< derived, valueType >( value ) {} \



///////////////////////////////////////////////////////////////////////////////

} // namespace Ishtar

#endif // __ISHTAR_VALUE_ORDINAL_INTEGER_H
